/*
Ryan Perry
April 25, 2008
*/

#include "Game.h"

Game::Game()
{
    /* Initialization begins.  frames, fps, seconds, and sdl ticks are initialized
        to zero to avoid complications.  The windows width and height are also
        specified here. */
    frames = 0;
    fps = 0;
    seconds = 0;
    sdlTicks = 0;
    WINDOW_WIDTH = 725;
    WINDOW_HEIGHT = 224;

    /* Now we begin to set up our SDL application.  The video mode flags are specified,
        SDL initilization options are given, surface pointers assigned a null value, and
        our text color is created by assigning values for its RGB channels, sperately. */
    SDL_VIDEOMODE_FLAGS = SDL_HWSURFACE | SDL_DOUBLEBUF;
    SDL_INIT_FLAGS = SDL_INIT_TIMER | SDL_INIT_AUDIO | SDL_INIT_VIDEO;
    mainWindow = NULL;
    message = NULL;
    font = NULL;
    textColor.r = 255;
    textColor.g = 255;
    textColor.b = 255;

    /* Our initilization flags are used in SDL's initilization method.  Our window's caption
        and icon are set.  Here, we also disable the cursor over our window and initialize
        the SDL TTF library. */
    SDL_Init(SDL_INIT_FLAGS);
    SDL_WM_SetCaption("SDL Test - Ryan Perry", NULL);
    SDL_WM_SetIcon(IMG_Load("img\\icon.GIF"), NULL);
    SDL_ShowCursor(SDL_DISABLE);
    TTF_Init();

    /* Not much to say here, just loading up the frames for our DrawableObjs */
    background.addFrames(0,"img\\background1.gif",0);
    background.addFrames(0,"img\\background2.gif",0);
    silverSamurai.addFrames(0,"img\\SilverSamurai\\intro\\01_200.gif",200);
    silverSamurai.addFrames(0,"img\\SilverSamurai\\intro\\02_16.gif",16);
    silverSamurai.addFrames(0,"img\\SilverSamurai\\intro\\03_08.gif",8);
    silverSamurai.addFrames(0,"img\\SilverSamurai\\intro\\04_08.gif",8);
    silverSamurai.addFrames(0,"img\\SilverSamurai\\intro\\05_16.gif",16);
    silverSamurai.addFrames(0,"img\\SilverSamurai\\intro\\06_08.gif",8);
    silverSamurai.addFrames(0,"img\\SilverSamurai\\intro\\07_64.gif",64);
    silverSamurai.addFrames(0,"img\\SilverSamurai\\intro\\08_10.gif",10);
    silverSamurai.addFrames(0,"img\\SilverSamurai\\intro\\09_10.gif",10);
    silverSamurai.addFrames(0,"img\\SilverSamurai\\intro\\10_10.gif",10);
    silverSamurai.addFrames(0,"img\\SilverSamurai\\intro\\11_10.gif",10);
    silverSamurai.addFrames(0,"img\\SilverSamurai\\intro\\12_10.gif",10);
    silverSamurai.addFrames(0,"img\\SilverSamurai\\intro\\13_10.gif",10);
    silverSamurai.addFrames(0,"img\\SilverSamurai\\intro\\14_10.gif",10);
    silverSamurai.addFrames(0,"img\\SilverSamurai\\intro\\15_16.gif",16);
    silverSamurai.addFrames(0,"img\\SilverSamurai\\intro\\16_20.gif",20);
    silverSamurai.addFrames(0,"img\\SilverSamurai\\intro\\17_20.gif",20);
    silverSamurai.addFrames(0,"img\\SilverSamurai\\intro\\18_26.gif",26);
    silverSamurai.addFrames(0,"img\\SilverSamurai\\intro\\19_18.gif",18);
    silverSamurai.addFrames(0,"img\\SilverSamurai\\intro\\20_10.gif",10);
    silverSamurai.addFrames(0,"img\\SilverSamurai\\intro\\21_200.gif",200);
    silverSamurai.addFrames(1,"img\\SilverSamurai\\idle\\01_10.gif",10);
    silverSamurai.addFrames(1,"img\\SilverSamurai\\idle\\02_26.gif",26);
    silverSamurai.addFrames(1,"img\\SilverSamurai\\idle\\03_10.gif",10);
    silverSamurai.addFrames(1,"img\\SilverSamurai\\idle\\04_10.gif",10);
    silverSamurai.addFrames(1,"img\\SilverSamurai\\idle\\05_10.gif",10);
    silverSamurai.addFrames(1,"img\\SilverSamurai\\idle\\06_10.gif",10);
    silverSamurai.addFrames(1,"img\\SilverSamurai\\idle\\07_10.gif",10);
    silverSamurai.addFrames(1,"img\\SilverSamurai\\idle\\08_10.gif",10);
    silverSamurai.addFrames(1,"img\\SilverSamurai\\idle\\09_10.gif",10);
    silverSamurai.addFrames(1,"img\\SilverSamurai\\idle\\10_10.gif",10);
    silverSamurai.addFrames(1,"img\\SilverSamurai\\idle\\11_10.gif",10);
    silverSamurai.addFrames(1,"img\\SilverSamurai\\idle\\12_10.gif",10);
    silverSamurai.addFrames(1,"img\\SilverSamurai\\idle\\13_10.gif",10);
    silverSamurai.setAnimation(0);
}
bool Game::runGame()
{
    /* The video mode flags set earlier are used here, along with our previously
        set window width and height.  For information on these flags
        and the initialization flags, see the SDL documentation's "Video" and
        "Initialization" sections. 32 is our bits per pixel. */
    mainWindow = SDL_SetVideoMode(WINDOW_WIDTH, WINDOW_HEIGHT, 32, SDL_VIDEOMODE_FLAGS);

    /* To display text, we need to set a font.  Here, we set our font to Anndale, size 12.
        Next, we bold our font. */
    font = TTF_OpenFont("AndaleMo.ttf", 12);
    TTF_SetFontStyle(font, TTF_STYLE_BOLD);

    /* This is where the magic happens.  This loop will continue until we receive a quit
        signal from our SDL window.  Until then, we trudge through our frame draw routine. */
    while(!receivedQuit()) {

        /* The next chunk of code is implemented to calculate and display the FPS in our
            SDL window.  Kind of unnecessary/ridiculous to have FPS tracking in a 2D fighter,
            but it's moreso for keeping tabs on performance (memory leaks?) */
        frames++;
        sdlTicks = SDL_GetTicks();
        if (sdlTicks >= 1000) {
            seconds = (sdlTicks / 1000);
            fps = frames / seconds;
            if (!(sdlTicks % 250))
            {
                fpsDisplay.str("");
                fpsDisplay << fps;
                fpsDisplay << " fps";
                /* After calculating our FPS and whipping up our string to display, we clear our
                    our old reading from the "message" surface and assign the new one. */
                SDL_FreeSurface(message);
                message = TTF_RenderText_Solid(font, fpsDisplay.str().c_str(), textColor);
            }
        }

        /* Currently, the input functionality is just for testing purposes.  Nothing here will
            remain in the final game.  It works by grabbing the current key state from SDL
            (key down = 1, key up = 1) and testing certain indexes with SDL's SDLK variables.
            The SDLK variables hold numerical values that correspond to their key's position
            in the array. */
        Uint8 *keystate = SDL_GetKeyState(NULL);
        if (keystate[SDLK_t])
            silverSamurai.setDoLoop(true);
        if (keystate[SDLK_f])
            silverSamurai.setDoLoop(false);
        if (keystate[SDLK_LEFTBRACKET])
            background.setFrame(0);
        if (keystate[SDLK_RIGHTBRACKET])
            background.setFrame(1);
        if (keystate[SDLK_a])
            silverSamurai.setAnimation(0);
        if (keystate[SDLK_s])
            silverSamurai.setAnimation(1);

        /* Draw!  My once mighty Graphics class's draw method has been whittled
            down to almost nothing.  Now it's merely a static method that's
            a wrapper for SDL's own draw.  Dynamic frame information is held
            and processed within DrawableObj.  "getCurrentFrame" static gets
            the current frame without advancing animation.  "getCurrentFrame"
            does the same, only advancing the animation after the read. */
        Graphics::draw(mainWindow, background.getCurrentFrameStatic(), 0, 0);
        Graphics::draw(mainWindow, silverSamurai.getCurrentFrame(), 300, 85);
        Graphics::draw(mainWindow, message, 10, 10);

        /* Since we set up double buffering in our video mode flags, we can use
            SDL's "flip" method which swaps the buffers and creates a more smooth
            transition between draws.  This only works on hardware supporting
            double buffering.  If double buffering isn't available, SDL requires
            the usage of "SDL_UpdateRect." */
        SDL_Flip(mainWindow);
    }

    return false;
}

/* Returns true if SDL fires a quit signal.  This is checked by looping through all
    of SDL's broadcasted event codes in search of SDL_QUIT. It was created to run
    before each of the draw iterations. */
bool Game::receivedQuit()
{
    SDL_Event sdlEvent;
    while (SDL_PollEvent(&sdlEvent))
    {
        if (sdlEvent.type == SDL_QUIT)
            return true;
    }
    return false;
}

/* A regular ol' constructor.  SDL_FreeSurface is the rough equivalent of deleting
    an object.  In this case, it'd be a surface.  TTF_CloseFont does the same, but
    with a font object.  Afterwards, we call on TTF and SDL's clean-up routines. */
Game::~Game()
{
    SDL_FreeSurface(mainWindow);
    SDL_FreeSurface(message);
    TTF_CloseFont(font);
    TTF_Quit();
    SDL_Quit();
}
